package com.mxl.service.cashorder.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.mxl.common.StringUtil;
import com.mxl.common.helper.ResponseErrorCode;
import com.mxl.common.rule.RuleEngine;
import com.mxl.dao.cashorder.impl.ChargeChannelDaoImpl;
import com.mxl.dao.cashorder.model.ChargeChannel;
import com.mxl.service.cashorder.GatewayPayOrderService;
import com.mxl.service.cashorder.GatewayProcessService;
import com.mxl.service.cashorder.dto.CashOrderRequest;
import com.mxl.service.cashorder.dto.SelectChannelDto;
import com.mxl.service.channel.adapter.ChargeService;
import com.mxl.service.dto.ChargeRequest;
import com.mxl.service.exception.AppServiceException;

/**
 * 网关收单核心处理 包括直连和定制的处理
 * 
 * @author Administrator
 * 
 */

@Service("gatewayProcessService")
public class GatewayProcessServiceImpl implements GatewayProcessService {
	private static final Logger logger = LoggerFactory
			.getLogger(GatewayProcessServiceImpl.class);
	private static final SimpleDateFormat dFormat = new SimpleDateFormat(
			"yyyyMMddHHmmss");
	private static final java.util.Random r = new java.util.Random();

	@Resource(name = "gatewayEngine")
	private RuleEngine gatewayEngine;

	@Resource(name = "chargeService")
	private ChargeService chargeService;

	@Resource(name = "chargeChannelDao")
	private ChargeChannelDaoImpl chargeChannelDao;

	@Resource(name = "gatewayPayOrderService")
	private GatewayPayOrderService gatewayPayOrderService;

	// private OrderFulfillerService OrderFulfillerService;

	/**
	 * 收单处理 卡号和卡密验证 保持销卡订单--直接反馈前台 然后消息放入队列.
	 */
	public String process(CashOrderRequest request) {
		// 验证卡号 卡密
		try {
			gatewayEngine.processRequest(request);
		} catch (Exception e) {
			request.setMsgId(ResponseErrorCode.FAIL.getValue());
			logger.error(
					"GatewayDispatchServiceImpl gatewayEngine fail----membercode orderId:"
							+ request.getOrderId(), e);

		}
		if (!StringUtil.isEmpty(request.getMsgId())) {
			throw new AppServiceException(request.getMsgId());
		}
		// 保持销卡订单 以及卡信息 此处设置卡的状态时已使用 后面渠道告诉我们失败后 再修改状态为未使用
		gatewayPayOrderService.saveGateWayOrder(request);
		chargeService.charge(wrapChargeRequest(request));
		// 匹配Fulfillment 以后可以拆分开来。
		// try {
		// OrderFulfillerService.fulfillOrder(wrapFulOrder(request, pOrder
		// .getId(), gOrder.getRate()));
		// } catch (NoMatchingMobileException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		return null;
	}

	// private FulfillOrderRequest wrapFulOrder(CashOrderRequest request,
	// Long pId, Long rate) {
	// FulfillOrderRequest order = new FulfillOrderRequest();
	// try {
	// BeanUtils.copyProperties(request, order);
	// order.setPId(pId);
	// order.setDiscount(rate);
	// // 设置當前兑换率
	// } catch (IllegalAccessException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// } catch (InvocationTargetException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	// return order;
	// }

	private ChargeRequest wrapChargeRequest(CashOrderRequest request) {
		ChargeRequest req = new ChargeRequest();
		req.setCardNo(request.getCardNo());
		req.setCarPwd(request.getCardPwd());
		req.setChargeAmount(request.getSelectAmount()); // / 直连直接是订单的金额
		req.setChannelCode(selectChargeChannel(request));
		req.setSeqNo(request.getSeqNo());
		return req;
	}

	private String selectChargeChannel(CashOrderRequest request) {
		SelectChannelDto dto = new SelectChannelDto();
		dto.setBossType(request.getBossType());
		dto.setCardRegion(request.getCardRegion());
		dto.setCardType(request.getCardType());
		dto.setMemberCode(request.getMemberCode());
		dto.setSelectAmount(new BigDecimal(request.getSelectAmount()).divide(
				new BigDecimal(100)).toString());
		logger.info("gateay selectChargeChannel..........." + dto.toString());
		List<ChargeChannel> channels = chargeChannelDao
				.queryAvailableChannel(dto);
		if (channels == null || channels.isEmpty()) {
			throw new AppServiceException(
					ResponseErrorCode.CHARGE_CHANNEL_NOT_AVAILABLE.getValue());
		}
		// 公司代码 选择渠道
		return select(channels);
	}

	private String select(List<ChargeChannel> channels) {
		int totalAssignRate = 0;
		if (channels.size() == 1) {
			logger.info("***********the only one channel code=="
					+ channels.get(0).getCode());
			return channels.get(0).getCode();
		}
		for (ChargeChannel c : channels) {
			totalAssignRate = totalAssignRate + c.getAssignRate().intValue();
		}
		int index = r.nextInt(totalAssignRate);
		ChargeChannel d = null;
		for (int i = 0; i < channels.size(); i++) {
			int a = 0;
			for (int j = 0; j < i + 1; j++) {
				d = channels.get(j);
				a = a + d.getAssignRate().intValue();
			}
			if (a >= index) {
				break;
			}
		}
		return d.getCode();
	}
}
